//! 计算消息需要花费的手续费
//!
//!

use crate::{bean::message::message_type::MessageType, core::constant, error::Error};
use num_bigint::BigInt;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
struct Fee {
    r#type: MessageType,
    remark: Option<String>,
    context: Option<String>,
}

pub fn calculate_msg_fee(message: &str) -> Result<BigInt, Error> {
    let fee: Fee = serde_json::from_str(message)?;
    if fee.r#type == MessageType::Transactions {
        Ok(calculate_fee_by_data(fee.remark))
    } else if fee.r#type == MessageType::Text {
        Ok(calculate_fee_by_data(fee.context))
    } else {
        Ok(calculate_fee_by_data(None))
    }
}

/// 计算消息需要花费的手续费
/// data： 附加消息或者数据
/// 返回手续费
pub fn calculate_fee_by_data(data: Option<String>) -> BigInt {
    let len = if data.is_none() || data.as_ref().unwrap().is_empty() {
        0
    } else {
        data.unwrap().len()
    };
    calculate_fee_by_len(len as i64)
}

/// 计算消息需要花费的手续费
/// 附加信息或者数据的长度
/// 返回手续费
pub fn calculate_fee_by_len(datalen: i64) -> BigInt {
    let fee = &BigInt::from(datalen) * &*constant::NRG_PEER_KBYTE / 1024;
    &fee + &*constant::BASE_NRG
}

#[cfg(test)]
mod tests {
    use crate::bean::message::fee::{
        calculate_fee_by_data, calculate_fee_by_len, calculate_msg_fee,
    };
    use serde_json::json;

    #[test]
    fn test_calculate_fee() {
        let msg = json!({"type": 1, "remark": "hello"}).to_string();
        let fee = calculate_msg_fee(&msg).unwrap();
        println!("{}", fee);

        let fee = calculate_fee_by_len(5);
        println!("{}", fee);

        let fee = calculate_fee_by_data(None);
        println!("{}", fee);

        let fee = calculate_fee_by_len(0);
        println!("{}", fee);
    }
}
